package com.gluz.gluz_flutter;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugins.imagepicker.Messages;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 人脸识别SDK相关导入
import com.face.lv5.sdk.bean.FaceliveLocalFileInfo;
import com.face.lv5.sdk.manager.FaceLiveDetectConfig;
import com.face.lv5.sdk.manager.FaceLiveManager;
import com.face.lv5.sdk.manager.FaceLiveDetectListener;
import com.permissionx.guolindev.PermissionX;
import com.permissionx.guolindev.callback.RequestCallback;

// Android相关导入
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.projection.MediaProjectionManager;
import android.os.IBinder;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;


/**
 * Android端NativeBridge封装类
 * 负责处理Flutter和Android原生代码之间的通信
 */
public class NativeBridge implements MethodCallHandler, EventChannel.StreamHandler {
    
    private static final String TAG = "NativeBridge";
    private static final String METHOD_CHANNEL_NAME = "native_bridge";
    private static final String EVENT_CHANNEL_NAME = "native_events";
    
    // 单例实例
    private static volatile NativeBridge INSTANCE;
    
    private final Context context;
    
    // 方法通道
    private MethodChannel methodChannel;
    
    // 事件通道
    private EventChannel eventChannel;
    
        // 事件发送器
    private EventChannel.EventSink eventSink;
    
    // 人脸识别相关变量
    private static final String HOST = "https://api.yljz.com"; // 请替换为实际的服务器地址
    private String lang = "zh"; // 默认中文
    private RecordService mRecordService; // 录制服务
    private boolean mIsBinded = false;
    private ServiceConnection connection;
    private MediaProjectionManager projectionManager;
    
    private NativeBridge(Context context) {
        this.context = context;
    }
    
    public static NativeBridge getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (NativeBridge.class) {
                if (INSTANCE == null) {
                    INSTANCE = new NativeBridge(context);
                }
            }
        }
        return INSTANCE;
    }
    
    /**
     * 初始化NativeBridge
     */
    public void initialize(io.flutter.plugin.common.BinaryMessenger messenger) {
        // 设置方法通道
        methodChannel = new MethodChannel(messenger, METHOD_CHANNEL_NAME);
        methodChannel.setMethodCallHandler(this);
        
        // 设置事件通道
        eventChannel = new EventChannel(messenger, EVENT_CHANNEL_NAME);
        eventChannel.setStreamHandler(this);
        Log.d(TAG, "Android NativeBridge initialized successfully");
    }
    
    /**
     * 处理来自Flutter的方法调用
     */
    @Override
    public void onMethodCall(MethodCall call, Result result) {
        try {
            switch (call.method) {
                case "showToast":
                    String message = call.argument("message");
                    if (message == null) message = "";
                    boolean success = showToast(message);
                    result.success(success);
                    break;
                case "faceAuth":
                    String token = (String) (((Map) call.arguments).get("token"));
                    if (token == null || token.isEmpty()) {
                        result.success(false);
                    } else {
                        faceAuth(token, result);
                    }
                    break;
                case "requestMediaProjection":
                    // 请求MediaProjection权限
                    requestMediaProjection(result);
                    break;
                case "setMediaProjectionData":
                    // 设置MediaProjection数据
                    if (call.hasArgument("resultCode") && call.hasArgument("data")) {
                        int resultCode = call.argument("resultCode");
                        // 注意：Intent不能直接通过Flutter传递，需要通过其他方式处理
                        result.success(true);
                    } else {
                        result.error("INVALID_ARGUMENTS", "缺少必要参数", null);
                    }
                    break;
                default:
                    result.notImplemented();
                    break;
            }
        } catch (Exception e) {
            Log.e(TAG, "Error handling method call " + call.method + ": " + e.getMessage());
            result.error("NATIVE_ERROR", "Error handling method call: " + e.getMessage(), null);
        }
    }
    
    /**
     * 事件通道流监听器设置
     */
    @Override
    public void onListen(Object arguments, EventChannel.EventSink events) {
        this.eventSink = events;
        Log.d(TAG, "Event channel listener attached");
    }
    
    /**
     * 事件通道流监听器取消
     */
    @Override
    public void onCancel(Object arguments) {
        this.eventSink = null;
        Log.d(TAG, "Event channel listener detached");
    }

    
    /**
     * 显示Toast消息
     */
    private boolean showToast(String message) {
        try {
            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Failed to show toast: " + e.getMessage());
            return false;
        }
    }


    /**
     * 调用Flutter方法获取用户信息
     */
    public void getUserInfoFromFlutter(final MapResultCallback callback) {
        if (methodChannel != null) {
            methodChannel.invokeMethod("getUserInfo", null, new Result() {
                @Override
                public void success(Object result) {
                    if (result instanceof Map) {
                        @SuppressWarnings("unchecked")
                        Map<String, Object> resultMap = (Map<String, Object>) result;
                        callback.onResult(resultMap);
                    } else {
                        callback.onResult(null);
                    }
                }
                
                @Override
                public void error(String errorCode, String errorMessage, Object errorDetails) {
                    Log.e(TAG, "Error getting user info: " + errorMessage);
                    callback.onResult(null);
                }
                
                @Override
                public void notImplemented() {
                    Log.e(TAG, "getUserInfo method not implemented");
                    callback.onResult(null);
                }
            });
        }
    }
    
    /**
     * 释放资源
     */
    public void dispose() {
        try {
            // 清理通道
            if (methodChannel != null) {
                methodChannel.setMethodCallHandler(null);
                methodChannel = null;
            }
            
            if (eventChannel != null) {
                eventChannel.setStreamHandler(null);
                eventChannel = null;
            }
            
            eventSink = null;
            
            Log.d(TAG, "Android NativeBridge disposed");
        } catch (Exception e) {
            Log.e(TAG, "Error disposing NativeBridge: " + e.getMessage());
        }
    }
    
    /**
     * 用户信息回调接口
     */
    public interface MapResultCallback {
        void onResult(Map<String, Object> userInfo);
    }

    private void faceAuth(String token, Result res) {
        // 检查是否有MediaProjection权限
        if (projectionManager == null) {
            projectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        }
        
        // 如果没有录制服务，先启动录制服务
        if (mRecordService == null) {
            startRecordService();
            res.error("NO_MEDIA_PROJECTION", "需要屏幕录制权限", null);
            return;
        }

        requestPermissionIfNeeded(new RequestCallback() {
            @Override
            public void onResult(boolean allGranted, @NonNull List<String> grantedList, @NonNull List<String> deniedList) {
                if (allGranted) {
                    Log.e("wsy", "allGranted = " + allGranted);


                    String modelPath = saveAssets("facelivemodel.bin", "model");
                    FaceLiveDetectConfig config = new FaceLiveDetectConfig();
                    config.setBizToken(token);
                    config.setHost(HOST);
                    /**
                     * 模型传入支持两种方式： 1 通过ModelPath进行设置；2 可以将facelivemodel.bin 文件放入app的raw目录下供SDK内部读取
                     * ps:两者皆提供SDK内部优先使用ModelPath下的model文件
                     */
                    config.setModelPath(modelPath);
                    config.setMediaProjection(mRecordService == null ? null : mRecordService.getMediaProjection());
                    config.setLanguage(lang);

                    FaceLiveManager.getInstance().startDetect(context, config, new FaceLiveDetectListener() {
                        @Override
                        public void onPreDetectFinish(int errorCode, String errorMessage) {
                            Log.e("finauthv5", "onPreDetectFinish : errorCode=" + errorCode + ",errorMessage=" + errorMessage);
                        }

                        @Override
                        public void onDetectFinish(int errorCode, String errorMessage, String bizToken) {
                            Log.e("finauthv5", "onDetectFinish : errorCode=" + errorCode + ",errorMessage=" + errorMessage);
                            /**
                             * 此处是活体检测的结果回调，返回码1000代表成功，可以调用verify接口。其他都是错误。只有成功时才可以进行verify，否则没有意义，甚至会出现一些错误，望注意！
                             */
                            if (errorCode == 1000) {
                                //成功了 走正常的逻辑就行了
                                res.success(true);
                            } else {
                                //失败的业务处理
                            }

                            if (mRecordService != null && mRecordService.getMediaProjection() != null) {
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                    mRecordService.getMediaProjection().stop();
                                }
                                mRecordService.setMediaProjection(null);
                            }
                            if (mIsBinded) {
                                mIsBinded = false;
                            }
                            if (projectionManager != null) {
                                projectionManager = null;
                            }
                        }

                        @Override
                        public void onLivenessFileCallback(String livenessFilePath) {

                            Log.e("finauthv5", "onLivenessFileCallback : livenessFilePath=" + livenessFilePath);
				/*
				该回调方法可以获取到留存到本地的活体数据的路径。
				*/
                        }

                        @Override
                        public void onLivenessLocalFileCallBack(FaceliveLocalFileInfo faceliveLocalFileInfo) {

                        }

                    });

                }
                Log.e("wsy", "allGranted2 = " + allGranted);
            }
        });

        

    }
    
    // 启动录制服务
    private void startRecordService() {
        if (projectionManager == null) {
            projectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        }
        
        // 这里需要通过Flutter端传入MediaProjection的resultCode和data
        // 暂时先绑定服务，等待Flutter端传入MediaProjection数据
        Intent intent = new Intent(context, RecordService.class);
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                RecordService.RecordBinder binder = (RecordService.RecordBinder) service;
                mRecordService = binder.getRecordService();
                mIsBinded = true;
                Log.d(TAG, "RecordService connected");
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                mRecordService = null;
                mIsBinded = false;
                Log.d(TAG, "RecordService disconnected");
            }
        };
        
        context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }
    
    // 设置MediaProjection数据（由Flutter端调用）
    public void setMediaProjectionData(int resultCode, Intent data) {
        if (mRecordService != null) {
            Intent intent = new Intent();
            intent.putExtra("code", resultCode);
            intent.putExtra("data", data);
            mRecordService.onBind(intent);
        }
    }
    
    // 请求MediaProjection权限
    private void requestMediaProjection(Result result) {
        if (projectionManager == null) {
            projectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        }
        
        // 启动录制服务
        startRecordService();
        
        // 通知Flutter端需要请求MediaProjection权限
        result.success("NEED_PERMISSION");
    }

    private String saveAssets(String fileName, String path) {
        File dir = new File(context.getExternalFilesDir("face"), path);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                return null;
            }
        }
        File file = new File(dir, fileName);

        FileOutputStream fos = null;
        InputStream is = null;
        String ret = null;
        try {
            int count;
            byte[] buffer = new byte[1024];
            fos = new FileOutputStream(file);
            is = context.getAssets().open(fileName);
            while ((count = is.read(buffer)) != -1) {
                fos.write(buffer, 0, count);
            }

            ret = file.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (fos != null) fos.close();
                if (is != null) is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    private void requestPermissionIfNeeded(RequestCallback requestCallback) {
        List<String> permissions = Collections.singletonList(Manifest.permission.CAMERA);

        boolean allGranted = true;
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
            }
        }
        if (allGranted) {
            requestCallback.onResult(true, permissions, new ArrayList<>());
            return;
        }

        // 检查context是否为FragmentActivity类型
        if (context instanceof FragmentActivity) {
            PermissionX.init((FragmentActivity) context).permissions(permissions)
                    .onExplainRequestReason((scope, deniedList) -> {
                        scope.showRequestReasonDialog(deniedList,
                                "我们将要申请一下权限，用于扩展功能的使用",
                                "同意",
                                "取消");
                    }).onExplainRequestReason((scope, deniedList) -> {
                        scope.showRequestReasonDialog(deniedList,
                                "我们将要申请一下权限，用于扩展功能的使用",
                                "同意",
                                "取消");
                    }).onForwardToSettings((scope, deniedList) -> scope.showForwardToSettingsDialog(deniedList,
                            "我们将要申请一下权限，用于扩展功能的使用",
                            "同意",
                            "取消")).request(new RequestCallback() {
                        @Override
                        public void onResult(boolean allGranted, @NonNull List<String> grantedList,
                                             @NonNull List<String> deniedList) {
                            if (requestCallback != null) {
                                requestCallback.onResult(allGranted, grantedList, deniedList);
                            }
                        }
                    });
        } else {
            // 如果不是FragmentActivity，直接返回权限已授予（假设权限已经通过其他方式获取）
            Log.w(TAG, "Context is not FragmentActivity, skipping permission request");
            requestCallback.onResult(true, permissions, new ArrayList<>());
        }
    }
} 